<template>
  <el-upload action="/api/upload" multiple :limit="limit" :on-exceed="handleExceed" :before-upload="beforeUpload"
    :on-success="handleSuccess" :auto-upload="false" :on-error="handleError" v-model:file-list="fileList"
    list-type="picture-card">
    <el-icon>
      <Plus />
    </el-icon>
    <template #file="{ file }">
      <div class="file-item">
        <img v-if="isImage(file)" :src="file.url" class="file-thumbnail" />
        <div v-else class="file-icon">
          <el-icon>
            <Document />
          </el-icon>
        </div>
        <span class="file-name">{{ file.name }}</span>
        <span class="file-actions">
          <el-icon @click="handlePreview(file)">
            <View />
          </el-icon>
          <el-icon @click="handleRemove(file)">
            <Delete />
          </el-icon>
        </span>
      </div>
    </template>
  </el-upload>
</template>

<script setup>
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, Document, View, Delete } from '@element-plus/icons-vue'

const props = defineProps({
  limit: {
    type: Number,
    default: 5
  },
  fileTypes: {
    type: Array,
    default: () => ['image/jpeg', 'image/png', 'application/pdf']
  },
  maxSize: {
    type: Number, // MB
    default: 10
  },
  modelValue: { type: Array, default: () => [] },
})

const emit = defineEmits(['upload-success', 'upload-error', 'update:modelValue'])

const fileList = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})



const isImage = (file) => {
  return file.type?.startsWith('image/') || /\.(jpg|jpeg|png|gif)$/i.test(file.name)
}

const handleExceed = () => {
  ElMessage.warning(`最多上传 ${props.limit} 个文件`)
}

const beforeUpload = (file) => {
  const isTypeValid = props.fileTypes.includes(file.type)
  const isSizeValid = file.size / 1024 / 1024 < props.maxSize

  if (!isTypeValid) {
    ElMessage.error(`仅支持 ${props.fileTypes.join(', ')} 格式`)
    return false
  }

  if (!isSizeValid) {
    ElMessage.error(`文件大小不能超过 ${props.maxSize}MB`)
    return false
  }

  return true
}

const handleSuccess = (response, file) => {
  emit('upload-success', { response, file })
}

const handleError = (error, file) => {
  emit('upload-error', { error, file })
}

const handlePreview = (file) => {
  if (isImage(file)) {
    window.open(file.url)
  } else {
    ElMessage.info('该文件类型不支持预览')
  }
}

const handleRemove = (file) => {
  fileList.value = fileList.value.filter(item => item.uid !== file.uid)
}
</script>

<style scoped>
.file-item {
  position: relative;
  width: 100%;
  height: 100%;
}

.file-thumbnail {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.file-icon {
  font-size: 40px;
  color: #409EFF;
}

.file-name {
  display: block;
  margin-top: 5px;
  text-align: center;
}

.file-actions {
  position: absolute;
  right: 5px;
  top: 5px;
  opacity: 0;
  transition: opacity .3s;
}

.file-item:hover .file-actions {
  opacity: 1;
}

:deep(.el-upload--picture-card),
:deep(.el-upload-list--picture-card .el-upload-list__item) {
  width: 80px;
  height: 80px;
}

/* 调整图标和文字位置 */
:deep(.el-upload--picture-card) {
  line-height: 80px;
}

:deep(.el-upload-list__item-actions) {
  line-height: inherit;
  /* 继承父元素行高 */
}
</style>
